package com.ddwl.user.service;

import com.ddwl.common.constant.*;
import com.ddwl.schema.bo.user.ProfitApplyQueryBo;
import com.ddwl.schema.bo.user.ProfitApplyRejectBo;
import com.ddwl.schema.bo.user.ProfitApplySubmitBo;
import com.ddwl.schema.vo.user.ProfitApplyVo;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.GateApi;
import com.ddwl.common.feign.api.WalletApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.gate.DingTalkBo;
import com.ddwl.schema.bo.gate.PushWxMsgBo;
import com.ddwl.schema.util.DateUtil;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.user.dao.ProfitApplyDao;
import com.ddwl.user.dao.model.ProfitApply;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类ProfitServer.java的实现描述：推广申请服务
 *
 * @author zach
 * @Date :2020-06-23 11:06.
 */
@Slf4j
@Service
public class ProfitApplyServer {

    @Resource
    private ProfitApplyDao profitApplyDao;

    @Resource
    private UserService userService;


    @Resource
    private GateApi gateApi;
    @Resource
    private WalletApi walletApi;
    @Resource
    private RabbitTemplate rabbitTemplate;


    /**
     * 查询审批通过的用户
     * @return
     */
    public List<ProfitApplyVo> querySuccessfulApply(){
        return BeanConverUtils.convertBeanList(profitApplyDao.queryApply(),ProfitApplyVo.class);
    }


    /**
     * 代理提交审批
     * @param applyBo
     */
    public void submitProfitApply(ProfitApplySubmitBo applyBo) throws Exception {
        ParamException.isFalse(IdcardUtil.isValidCard(applyBo.getIdCard()),"请输入正确身份证号");
        ParamException.isNull(gateApi.geoRegion(applyBo.getRegionId()).getResult(),"请输入正确的地址");
        ProfitApply profitApply = BeanConverUtils.convertBean(applyBo,ProfitApply.class);
        ProfitApply apply = profitApplyDao.queryUserApply(applyBo.getUserId());
        ProfitApply idCard = profitApplyDao.queryUserApplyByIdCard(applyBo.getIdCard());
        ProfitApply phone = profitApplyDao.queryUserApplyByPhone(applyBo.getPhone());
        profitApply.setStatus(BaseEnum.ApplyEnum.PRE.getCode());
        if(apply!=null){
            ParamException.isTrue(BaseEnum.ApplyEnum.SUCCEED.getCode().equals(apply.getStatus()),"已经审批通过了请勿重复提交");
            ParamException.isFalse(applyBo.getPhone().equals(phone.getPhone()),"该手机号已经审批通过了请勿重复提交");
            ParamException.isFalse(applyBo.getIdCard().equals(idCard.getIdCard()),"该身份证已经审批通过了请勿重复提交");
            profitApply.setId(apply.getId());
            profitApplyDao.updateByPrimaryKeySelective(profitApply);
        }else {
            ParamException.isNotNull(idCard,"该身份证已经审批通过了请勿重复提交");
            ParamException.isNotNull(phone,"该手机号已经审批通过了请勿重复提交");
            profitApplyDao.insert(profitApply);
        }
        //发送钉钉消息
        DingTalkBo bo1=new DingTalkBo();
        bo1.setMessage("");
        bo1.setChannel(StatisticsEnum.channel.UN_APPROVE_IDCARD.getId());
        rabbitTemplate.convertAndSend(RabbitMqConstants.DINGDING_TALK_MESSAGE,JSON.toJSONString(bo1));
    }

    @Transactional(rollbackFor = Exception.class)
    public void  approveApply(String applyId){
        ProfitApply apply = profitApplyDao.selectByPrimaryKey(applyId);
        ParamException.isNull(apply);
        apply.setStatus(BaseEnum.ApplyEnum.SUCCEED.getCode());
        profitApplyDao.updateByPrimaryKeySelective(apply);
        //userService.updateProfitLevel(apply.getUserId(), UserEnum.ProfitLevelEnum.ZONE.getLevel());
        //((ProfitApplyServer) AopContext.currentProxy()).wxNotify(apply);
    }

    @Async
    public void wxNotify(ProfitApply apply){
        //微信通知发送接口
        PushWxMsgBo pushWxMsgBo=new PushWxMsgBo();
        pushWxMsgBo.setUserId(apply.getUserId());
        Map<String,String> templateDate=new HashMap<>();
        pushWxMsgBo.setTemplateNum(WxEnum.WxMsgTemplate.TEMPLATEID3.getCode());
        templateDate.put(WxEnum.TEMPLATEINVOKE3.IDNAME.getCode(),apply.getIdName());
        templateDate.put(WxEnum.TEMPLATEINVOKE3.APPLYRESULT.getCode(),BaseEnum.ApplyEnum.SUCCEED.getName());
        templateDate.put(WxEnum.TEMPLATEINVOKE3.APPLYTIME.getCode(), DateUtil.formatDate(apply.getGmtModified(),DateUtil.DATE_TIME_FORMAT3));
        templateDate.put(WxEnum.TEMPLATEINVOKE3.APPLYSUB.getCode(),"恭喜您，您的审核已通过！");
        pushWxMsgBo.setTemplateDate(templateDate);
    }



    /**
     * 拒绝审批
     * @param profitApplyRejectBo
     */
    public void  rejectApply(ProfitApplyRejectBo profitApplyRejectBo){
        ProfitApply profitApply = new ProfitApply();
        profitApply.setId(profitApplyRejectBo.getApplyId());
        profitApply.setStatus(BaseEnum.ApplyEnum.FILL.getCode());
        if (StringUtils.hasText(profitApplyRejectBo.getRejectReason())) {
            profitApply.setRejectReason(profitApplyRejectBo.getRejectReason());
        }
        profitApplyDao.updateByPrimaryKeySelective(profitApply);
    }

    public ProfitApplyVo get(String applyId){
        return BeanConverUtils.convertBean(profitApplyDao.selectByPrimaryKey(applyId),ProfitApplyVo.class);
    }

    /**
     * 删除用户代理信息
     * @param applyId
     */
    public void delete(String applyId){
        ProfitApply apply = profitApplyDao.selectByPrimaryKey(applyId);
        if(apply!=null){
            profitApplyDao.deleteById(applyId);
            userService.removeUserDist(apply.getUserId());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public ProfitApplyVo getUserApply(String userId){
        return BeanConverUtils.convertBean(profitApplyDao.queryUserApply(userId),ProfitApplyVo.class);
    }


    public PageVo<ProfitApplyVo> page(PageBo<ProfitApplyQueryBo> pageBo){
        PageHelper.startPage(pageBo.getPage(),pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(),pageBo.isAsc()));
        PageInfo<ProfitApply> info = new PageInfo(profitApplyDao.queryApplyList(pageBo.getParam()));
        List<ProfitApplyVo> list = BeanConverUtils.convertBeanList(info.getList(),ProfitApplyVo.class);
        return new PageVo<>(info.getTotal(),pageBo.getPage(),pageBo.getPageSize(),list);
    }

    public Integer queryProfitApplyList(ProfitApplyQueryBo pageBo){
        Integer unProfitApply = profitApplyDao.queryApplyCount(pageBo);
        return unProfitApply;
    }

    public void batchSyncApplyUser() {
        log.info("method ProfitApplyServer.batchSyncApplyUser start");
        List<ProfitApplyVo> applyVoList=querySuccessfulApply();
        applyVoList.forEach((vo)->syncCreateFXUser(vo));
    }

    private void syncCreateFXUser(ProfitApplyVo vo) {
        log.info("method ProfitApplyServer.syncCreateFXUser start");
        log.info("parameter {}",JSON.toJSONString(vo));
        userService.createFXUser(vo);
    }

    public String getFXUser(String userId) {
        ProfitApply profitApply=profitApplyDao.queryUserApply(userId);
        if(null!=profitApply){
            return userService.getUserIdByMobile(profitApply.getPhone());
        }
        return null;
    }

    public void batchCorrectWalletInfo() {
        log.info("method ProfitApplyServer.correctWalletInfo start");
        List<ProfitApplyVo> applyVoList=querySuccessfulApply();
        if(!CollectionUtils.isEmpty(applyVoList)){
            applyVoList.forEach(profitApplyVo -> {
                correctWalletInfo(profitApplyVo);
            });
        }
    }

    private void correctWalletInfo(ProfitApplyVo profitApplyVo) {
        log.info("method ProfitApplyServer.correctWalletInfo start");
        log.info("parameter {}",JSON.toJSONString(profitApplyVo));
        String fxUserId = userService.getUserIdByMobile(profitApplyVo.getPhone());
        log.info("parameter fxUserId {}",fxUserId);
        String userId=profitApplyVo.getUserId();
        if (StrUtil.isNotEmpty(fxUserId) && StrUtil.isNotEmpty(userId)) {
            walletApi.correctWalletInfo(fxUserId, userId);
        }
    }
}
